"""\
GameFSM is a game-controlling FSM class

There six States in this FSM:
    MainMenu, GameLoad, GameRun, GamePause, Configure, GameOver

These method can be override
    DoGameLoadHandle
    DoGameRunHandle
    DoGamePauseHandle
    DoGameReConfigureHandle
    DoGameOverHandle
    DoGameTerminateHandle

GameFSM.__init__(self)
    Create a GameFSM.
"""

# event for main menu
from EventDefine import event_MAINMENU
# event for back to previous menu
from EventDefine import event_MENU_BACKTOPREVIOUS
# event for game-running manager
from Shell.data.GameEventDefine import event_GAME_BACKTOMAINMENU, event_GAME_GAMELOAD, event_GAME_GAMEOVER, event_GAME_GAMEPAUSE, event_GAME_GAMERESUME, event_GAME_GAMECONFIGURE
from direct.fsm import FSM
from Shell.gui.GamePauseMenuFrame import GamePauseMenuFrame
from Shell.gui.ConfigureMenuFrame import ConfigureMenuFrame
from Shell.gui.GameOverMenuFrame import GameOverMenuFrame

# state: MainMenu, GameLoad, GameRun, GamePause, GameOver
class GameFSM(FSM.FSM):
    def __init__(self):
        FSM.FSM.__init__(self, name = 'game fsm')
        self.IsGameAlive = False
        self.request('MainMenu')

    def enterMainMenu(self):
        if self.IsGameAlive:
            # back to main menu
            self.DoGameTerminateHandle() # game terminate
            self.IsGameAlive = False
            messenger.send(event_MAINMENU)
        # else: pass # initial state
        self.acceptOnce(event_GAME_GAMELOAD, self.demand, ["GameLoad"]) # start or load game

    def exitMainMenu(self):
        self.ignoreAll()
        # only one way to GameLoad

    def enterGameLoad(self):
        if self.IsGameAlive:
            self.DoGameTerminateHandle() # game terminate
        else:
            self.IsGameAlive = True
        self.DoGameLoadHandle()
        self.demand("GameRun")
        # only one way to GameRun

    #def exitGameLoad(self):
    #    pass

    def enterGameRun(self):
        self.acceptOnce(event_GAME_GAMEPAUSE, self.demand, ["GamePause"]) # for game pause
        self.acceptOnce(event_GAME_GAMEOVER, self.demand, ["GameOver"]) # for game over / next level
        self.DoGameRunHandle()

    def exitGameRun(self):
        self.ignoreAll()

    def enterGamePause(self):
        self.acceptOnce(event_GAME_GAMERESUME, self.demand, ["GameRun"])  # resume
        self.acceptOnce(event_GAME_GAMECONFIGURE, self.demand, ["GameConfigure"]) # configure
        self.acceptOnce(event_GAME_GAMELOAD, self.demand, ["GameLoad"]) # restart or load game
        self.acceptOnce(event_GAME_BACKTOMAINMENU, self.demand, ["MainMenu"]) # back to main menu
        self.DoGamePauseHandle()
        self.GamePauseMenuFrame = GamePauseMenuFrame()

    def exitGamePause(self):
        self.ignoreAll()
        self.GamePauseMenuFrame.destroy()

    def enterGameConfigure(self):
        self.acceptOnce(event_MENU_BACKTOPREVIOUS, self.demand, ["GamePause"]) # back to game pause
        self.ConfigureMenuFrame = ConfigureMenuFrame()

    def exitGameConfigure(self):
        self.ignoreAll()
        self.ConfigureMenuFrame.destroy()
        self.DoGameReConfigureHandle()

    def enterGameOver(self):
        self.acceptOnce(event_GAME_GAMELOAD, self.demand, ["GameLoad"]) # restart or load game
        self.acceptOnce(event_GAME_BACKTOMAINMENU, self.demand, ["MainMenu"]) # back to main menu
        self.DoGameOverHandle()
        self.GameOverMenuFrame = GameOverMenuFrame()

    def exitGameOver(self):
        self.ignoreAll()
        self.GameOverMenuFrame.destroy()

    # handler for override ------------------------------------------
    def DoGameLoadHandle(self, dictInfo):
        print 'DoGameLoadHandle'

    def DoGameRunHandle(self):
        print 'DoGameRunHandle'
        messenger.send(event_GAME_GAMEOVER)

    def DoGamePauseHandle(self):
        pass

    def DoGameReConfigureHandle(self):
        pass

    def DoGameOverHandle(self):
        print 'DoGameOverHandle'
        messenger.send(event_GAME_BACKTOMAINMENU)

    def DoGameTerminateHandle(self):
        print 'DoGameTerminateHandle'
